package com.example.a_lib.http

import android.app.Application
import com.example.a_lib.BuildConfig
import com.example.a_lib.config.ServerFlavorConfig
import com.example.a_lib.http.RetrofitFactory.DEFAULT_TIMEOUT_MILLISECONDS
import com.example.a_lib.http.api.ApiVersionInterceptor
import com.example.a_lib.http.interceptor.HttpLoggingInterceptor
import me.jessyan.retrofiturlmanager.RetrofitUrlManager
import okhttp3.ConnectionPool
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import java.net.Proxy
import java.util.concurrent.TimeUnit


/**
 * Created by xiedongdong on 2020/01/18
 */
class ComponentsClient {
    lateinit var client: Retrofit
    lateinit var mOkHttpClientBuilder: OkHttpClient.Builder

    companion object {
        lateinit var sContext: Application

        /**
         * 必须在全局Application先调用，获取context上下文，否则缓存无法使用
         */
        fun init(app: Application) {
            sContext = app
        }

        /*
        * img base url
        */
        var BASE_IMG_URL = ""

        /*
        * web base url
        */
        var BASE_WEB_URL = ""

        /*
        * api base url
        */
//        var BASE_API_URL = "https://www.wanandroid.com/"
        var BASE_API_URL = ServerFlavorConfig.API_BASE_URL_LEZHU_GENERAL

        private val CLIENT_MAP: MutableMap<String, ComponentsClient> = HashMap()

        @Synchronized
        fun getInstance(): ComponentsClient {
            return getInstance(BASE_API_URL)
        }

        @Synchronized
        fun getInstance(baseUrl: String): ComponentsClient {
            var client = CLIENT_MAP[baseUrl]
            if (client == null) {
                client = ComponentsClient()

                client.mOkHttpClientBuilder = RetrofitUrlManager.getInstance().with(OkHttpClient.Builder())
//                val mOkHttpClient: OkHttpClient.Builder = OkHttpClient.Builder()
                client.mOkHttpClientBuilder
                    .connectTimeout(DEFAULT_TIMEOUT_MILLISECONDS.toLong(), TimeUnit.MILLISECONDS)
                    .readTimeout(DEFAULT_TIMEOUT_MILLISECONDS.toLong(), TimeUnit.MILLISECONDS)
                    .writeTimeout(DEFAULT_TIMEOUT_MILLISECONDS.toLong(), TimeUnit.MILLISECONDS)
                //.cookieJar(new CookieJar(PersistentCookieStore.getInstance(context)))
//                    .addInterceptor(DynamicTimeoutInterceptor())
//                    .addInterceptor(ApiVersionInterceptor())
//                    .addInterceptor(HttpExceptionInterceptor())
//                    .addInterceptor(UserAgentInterceptor())

                if (BuildConfig.DEBUG) {
                    client.mOkHttpClientBuilder.addInterceptor(HttpLoggingInterceptor())
                }

                client.client = Retrofit.Builder()
                    .baseUrl(baseUrl)
                    .client(client.mOkHttpClientBuilder.build())
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .build()
                CLIENT_MAP[baseUrl] = client
            }
            return client
        }
    }



    //==================OkHttpClient设置拦截器、代理、连接池=====================//
    /**
     * 添加全局拦截器
     */
    fun addInterceptor(interceptor: Interceptor?): ComponentsClient {
        mOkHttpClientBuilder.addInterceptor(interceptor!!).build()
        return this
    }

    /**
     * 添加全局网络拦截器
     */
    fun addNetworkInterceptor(interceptor: Interceptor?): ComponentsClient {
        mOkHttpClientBuilder.addNetworkInterceptor(checkNotNull(interceptor) { "interceptor == null" })
        return this
    }

    /**
     * 全局设置代理
     */
    fun setOkproxy(proxy: Proxy?): ComponentsClient {
        mOkHttpClientBuilder.proxy(checkNotNull(proxy) { "mProxy == null" })
        return this
    }

    /**
     * 全局设置请求的连接池
     */
    fun setOkconnectionPool(connectionPool: ConnectionPool?): ComponentsClient {
        mOkHttpClientBuilder.connectionPool(checkNotNull(connectionPool) { "connectionPool == null" })
        return this
    }

    fun <T> provideService(t: Class<T>): T {
        return client.create(t)
    }


}